package beans;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import conversions.Conversions;
import dao.MembershipDao;
import dao.RepositoryDao;
import dao.ServerLogEntryDao;
import dao.UserDao;
import dto.DTOUser;
import dto.RepositoryDTO;
import enumerations.LogType;
import model.Folder;
import model.Membership;
import model.Repository;
import model.User;

/**
 * Session Bean implementation class RepositoryBean
 * @author Zsombor
 */
@Stateless

public class RepositoryBean implements RepositoryBeanRemote {


	@EJB
	Conversions conv;
	
	@EJB
	RepositoryDao dao;
	
	@EJB
	UserDao daoUser;
	
	@EJB
	MembershipDao daoMember;
	
	@EJB
	ServerLogEntryDao servLogEntryD;
	
	 
	public RepositoryBean() {
    }
	
	
	/**
     * Description: Add a new Repository to DB 
     * @author Zsolt
     * @param rDto RepositoryDTO
     * 
     * @author zahariem
     * Description zahariem: adding operation to serverLog
     */
	@Override
	public void addRepositoryDTO(RepositoryDTO rDto) {
		Folder rootF = dao.getFolderByID(0);
		Repository r = conv.fromDTOtoRepository(rDto,rootF);
		dao.addRepository(r);
		
		r.setFolder(dao.getFolderByID(r.getId()));
		dao.mergeRepository(r);
		
		Folder f = dao.getFolderByID(r.getId());
		User u = daoUser.getSupervisorByName(rDto.getUserID());
		User adminU = daoUser.getAdminUser();
		Membership m = conv.fromDTOtoMembership(rDto,f,u);
		dao.persistMembership(m);
		Membership m2 = conv.fromDTOtoMembership(rDto, f, adminU);
		dao.persistMembership(m2);
		String content ="Create repository for "+u.getId()+" "+ u.getName();
		servLogEntryD.insertOpToLog(LogType.create_repository, content, new Date(), daoUser.getAdminUser());
		
	} 

	/**
     * Description: Returns the folders that are in the tree of given repository
     * @author Zsombor
     * @param rDto RepositoryDTO
     */
	public List<Folder> getRefFolders(Folder folder){
		List<Folder> result = new ArrayList<Folder>();
		List<List<Folder>> listOfLists = new ArrayList<List<Folder>>();
		
		List<Folder> refFolders = dao.getFoldersById(folder.getId());
		result.addAll(refFolders);
		
		for(Folder f1:result){
			listOfLists.add(getRefFolders(f1));	
		}
		
		for(List<Folder> l:listOfLists){
			result.addAll(l);
		}
		
		return result;
	}
	
	/**
     * Description: Delete Repository from DB
     * @author Zsombor
     * @param rDto RepositoryDTO
     */
	@Override
	public void deleteRepository(int repositoryid) {
		Folder r;
		
		 r = dao.getFolderByID( repositoryid);
		 
		 
		List<Folder> result = getRefFolders(r);
		 
		 for(Folder f:result){
			 dao.deleteFolder(f);
		 }
		 
		dao.deleteRepository(r);
		String content ="Delete repository cu id-ul "+r.getId()+" si numele "+ r.getName();
		servLogEntryD.insertOpToLog(LogType.delete_repository, content, new Date(), daoUser.getAdminUser());
	}

	/**
     * Description: Change Repositories Supervisor in Member table
     * @author Zsolt
     * @param rDto RepositoryDTO
     * 
     * @author zahariem
     * Description zahariem: adding operation to serverLog
     */
	@Override
	public void changeSupervisor(RepositoryDTO rDto) {
		Membership m = daoMember.getMembershipByRepID("" + dao.getRepositoryByName(rDto.getRepName()));
		
		User lastSuperv = m.getUser();
		m.setSupervisor(0);
		daoMember.setSupervisor(daoUser.getSupervisorByName(rDto.getUserID()).getId(), dao.getRepositoryByName(rDto.getRepName()));
		
		dao.persistMembership(m);
		
		User currentSuperv = daoUser.getUserById(daoUser.getSupervisorByName(rDto.getUserID()).getId());
		
		String content = "Supervisor changed for repository " + rDto.getRepName()
				+ " from " + lastSuperv.getId() + " " +lastSuperv.getName()
				+ " to "+ currentSuperv.getId() + " " +currentSuperv.getName();
		
		servLogEntryD.insertOpToLog(LogType.transfer_rights, content, new Date(), daoUser.getAdminUser());
	}

	/**
     * Description: Get all usernames -> DTOUser.getAllUsers
     * @author Zsolt
     * @return DTOUser
     */
	@Override
	public DTOUser getAllUserNames() {
		return daoUser.getAllUserNames();
	}
	
	/**
     * Description: Get all repository names -> DTOUser.getAllUsers
     * @author Zsolt
     * @return RepositoryDTO
     */
	@Override
	public RepositoryDTO getAllRepositoryNames() {
		return dao.getAllRepositoryNames();
	}

	/**
	 * Description: Method that returns true if repository exists in DB
	 * @author Zsolt
	 * @param String repository name
	 * @return boolean
	 */
	@Override
	public boolean existsNameInDB(String enteredName) {
		return dao.existsRepositoryName(enteredName);
	}

	/**
	 * @author ieneir
	 * returns repositories list where user with id is not member
	 */

	@Override
	public List<RepositoryDTO> getRepositoriesWhereNotMember(Integer id) {
		List<RepositoryDTO> rDtoList=new ArrayList<RepositoryDTO>();
		List<Repository> rList = dao.getRepositoriesWhereNotMember(id);
		for (Repository r : rList)
		{
			rDtoList.add(conv.fromRepositoryToDto(r));
		}
		return rDtoList;
	}

	/**
	 * @author ieneir
	 * returns repositories list 
	 */
	@Override
	public List<RepositoryDTO> getAllRepositories() {
		List<RepositoryDTO> rDtoList=new ArrayList<RepositoryDTO>();
		List<Repository> rList = dao.getAllRepositories();
		for (Repository r : rList)
		{
			rDtoList.add(conv.fromRepositoryToDto(r));
		}
		return rDtoList;
	}
	
	/**
	 * @author fodorl 
	 * 
	 * zahariem: insert to serverLogEntry
	 * 
	 * @param idUser
	 * @param idRepository
	 */
	
	public void addUserToRepository(int idUser, int idRepository){
		Membership membership = new Membership();
		
		User user = daoUser.getUserById(idUser);
		Repository repository = dao.getRepositoryByID(idRepository);
				
		membership.setUser(user);
		membership.setSupervisor(0);
		membership.setFolder(repository);
				
		dao.persistMembership(membership);
		
		String content ="User"+user.getName()+"added to repository cu id-ul "+repository.getId()+" si numele "+ repository.getName();
		servLogEntryD.insertOpToLog(LogType.transfer_rights, content, new Date(), daoUser.getAdminUser());
		}
	
	/**
	 * Description get current RepID
	 * @author Zsolt
	 * @return String with current RepID
	 */
	@Override
	public String getRepID(RepositoryDTO rDto){
		String repName = rDto.getRepName();
		return String.valueOf(dao.getRepositoryByName(repName));
	}
	
	
	
}
